/*
 *  Rb3d4p.h
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 21/03/11
 *	Modified by Roberto Ortega 01/04/2011
 */

#ifndef _rb3d4p_h_
#define _rb3d4p_h_

#include "component.h"
#include "commonutil.h"
//#include "material.h"


using namespace std;

class Rb3d4p : public Component
{
public:
	
	//Mass
	double mass;
	
	//Local directions (vectors)
	vector<double> rj, rk, rl;
	
	// Principal moments of inertia
	double A, B, C;
	
	double partial_qddotOld;
/*	Data members from the base class Component
	int dim;					// Dimension, from the parent body
	int numDofs;				// Number of dofs
	int numDofsInertia;
	vector<string> pointNames;						// Names of the points belonging to the component
	map<string,Point*,less<string> > mPoints;		// Pointers to points belonging to the component
	// WARNING: pointNames and mPoints have different ordering
	vector<int> localGlob;			// Local-global numbering
	vector<int> localGlobInertia;	// Local-global numbering for dofs contributing inertia
	double time;					//Time (local)
	double deltaT;
	string matName;
	vector<double> q;			// Local position dofs
	vector<double> dq;			// Local velocity dofs
	vector<double> qC;			// Local converged position
	vector<double> dqC;			// Local converged velocity
	vector<double> Fi;			// Local contribution to the residual, inertia
	vector<double> Fq;			// Local contribution to the residual, function of q and dq
	vector<double> Ft;			// Local contribution to the residual, function of t
	vector< vector<double> > Ki;		// Local contribution to the tangent, inertia
	vector< vector<double> > Kq;		// Local contribution to the tangent from Fq, derivative of q
	vector< vector<double> > Kdq;		// Local contribution to the tangent from Fq, derivative of dq
	vector< vector<double> > M;		// Local contribution to the mass matrix
	double perturbation;			// For numerical differentiation
	int integratorType;
	double thetab;		// Ambient temperature
	bitset<4> dofT;		// Bitset for additive update dofs that belongs to the component
	vector<int> globalTNum;	// Global numbers of component dofs
	vector<double> vLagMul;	// Lagrange multipliers
	bool augLagFlag, augConvergence;
	vector<double> Phi;		// Constraint vector
	vector<vector<double> > dPhi;	// Jacobian of constraint vector
	vector<double> PhiC;		// Coverged Constraint vector
	double penalty;
	vector<double> FqLag;
	vector<double> FqPenalty;
	double FqRatio;
*/
	
	// Local Points And Elements **********************************************/

public:
	Rb3d4p();
	
	~Rb3d4p(){}
	
	Rb3d4p(double,
		   vector<string>&,
		   vector<vector<double> >&,
		   vector<double>&,
		   int);
	
	/** Virtual functions from base */
	void setDofs(void);
	
	void initializeGlobalDofs(vector<double> &, vector<double> &, const double &);
	
	void calcFi(const vector<double>&);
	
	void calcFq(const int&);
	
	void calcFt(const double&, const double&, const int&);
	
	void calcKi(double&);
	
	void calcKq(int);
	
	void calcKdq(double&);
	
	void calcM(const vector<double>&, const double &);
	
	void calcMLumped(const vector<double>&, const double &);
	
	void setMatAtComp(Material*);
	
	string getMatName()	{return matName;}
	
	void initializeCompRes(const bool&, const double&, const int&, const bool);
	
//	void initializeCompTang(const bool&, const bool&);
	void initializeCompTang(const bool&);
	
	void calcEner(double&, double&, double&, double&, double&, double&, double&, int&, vector<double>&, vector<double>&);
	
	void calcEntropy(double&, double&);
	
	void calcAM(vector<double>&, vector<double>&, vector<double>&);
	
	void updateComp(void);
	
	void setInitialConditions(vector<double>&, vector<double>&){}
	
	double getTemperature(void){};
	
	void setIniDofs(vector<double>&);
	
	void calcPhi(const vector<double>&);
	
	void calcDPhi(const vector<double>&);
	void calcMSmooth(const vector<double>&, const double&);
	void calcFSmooth(const vector<double>&, const vector<double>&, const double&);
	int checkState(void);
	
	/** Local functions */
	//double currentArea(double &);	/** Current area for given stretch */
	void makeM();

	/** Friend functions */
	friend double lTwoNorm(const vector<double>& v1);
	
	friend double lTwoNorm(const vector<double>& v1, const vector<double>& v2);
	
	friend void uVersor(const vector<double>& v1, const double & dis, const int& dim, vector<double>& u);
	
//	friend void uVersor(const vector<double>& v1, const vector<double>& v2, const double & dis, vector<double>& u);
	
	friend void printSTLVector(vector<double>& v);
	
	friend void printSTLMatrix(const vector< vector<double> >& m);
	
	friend void setZero(vector<double>& v);
	
	friend void setZero(vector<vector<double> >& mat);
	
	friend void inverse(vector<vector<double> >& mat);

};

#endif

